package it.polimi.dei.SeCo.LingPipe;

import it.polimi.dei.SeCo.Main;
import it.polimi.dei.SeCo.WordNet.WordNetTool;

import java.util.List;

import org.modeshape.common.text.Inflector;

import com.aliasi.dict.DictionaryEntry;
import com.aliasi.dict.MapDictionary;

import edu.smu.tspell.wordnet.NounSynset;
import edu.smu.tspell.wordnet.Synset;
import edu.smu.tspell.wordnet.SynsetType;

/**
 * @author Simone Benefico
 */
public class MapDictionaryManager {
	
	private MapDictionary<String> dictionary;
	
	/**
	 * Creates a dictionary with the given entries and complete it depending on the other parameters.
	 * @param entries list of Strings to add to the dictionary
	 * @param category category of the entries to add to the dictionary (i.e. PLACE, ADVERB OF PLACE, etc.)
	 * @param synsetsBool it tells whether the synsets of the entries should be added to the dictionary or not
	 * @param hyponymsBool it tells whether the hyponyms of the entries should be added to the dictionary or not
	 * @param hypernymsBool it tells whether the hypernyms of the entries should be added to the dictionary or not
	 * @param type type of the entries to add to the dictionary (i.e. NOUN, VERB, ADVERB, etc.)
	 */
	public MapDictionaryManager(String[] entries, String category, boolean synsetsBool, boolean hyponymsBool, boolean hypernymsBool, SynsetType type) {
		MapDictionary<String> dict = new MapDictionary<String>();
		Inflector infl = new Inflector();
		WordNetTool wn = new WordNetTool(Main.WORDNET_PATH);
		Synset[] synsets = null;
		NounSynset[] hyponyms = null;
		NounSynset[] hypernyms = null;
		List<String> synsetsStrings = null;
		List<String> hyponymsStrings = null;
		List<String> hypernymsStrings = null;
		String entry = new String();
		String newCategory = new String();
		for(int i = 0; i<entries.length; i++) {
			if(entries[i].endsWith(")"))
				entry = entries[i].substring(0, entries[i].lastIndexOf("(")).toLowerCase();
			else
				entry = entries[i];
			if(type.equals(SynsetType.ADVERB))
				newCategory=category+"_"+entry;
			else
				newCategory = category;
			if(dict.phraseEntryList(entry)==null || dict.phraseEntryList(entry).isEmpty()) {
				dict.addEntry(new DictionaryEntry<String>(entry,newCategory));
				if(type.equals(SynsetType.NOUN))
					dict.addEntry(new DictionaryEntry<String>(infl.pluralize(entry),newCategory));
			}
			else
				newCategory = dict.phraseEntryList(entry).get(0).category();
			if(synsetsBool) {
				synsets = wn.getSynsets(entry, type);
				if(synsets!=null) {
					synsetsStrings = wn.firstSynsetStrings(synsets);
					for(String string : synsetsStrings)
						if(dict.phraseEntryList(string)==null || dict.phraseEntryList(string).isEmpty()) 
							dict.addEntry(new DictionaryEntry<String>(string,newCategory));
				}
			}
			if(hyponymsBool && type.equals(SynsetType.NOUN)) {
				hyponyms = wn.getHyponyms(synsets);
				if(hyponyms!=null) {
					hyponymsStrings = wn.firstSynsetStrings(hyponyms);
					for(String string : hyponymsStrings)
						if(dict.phraseEntryList(string)==null || dict.phraseEntryList(string).isEmpty())
							dict.addEntry(new DictionaryEntry<String>(string,newCategory));
				}
			}
			if(hypernymsBool && type.equals(SynsetType.NOUN)) {
				hypernyms = wn.getHypernyms(synsets);
				if(hypernyms!=null) {
					hypernymsStrings = wn.firstSynsetStrings(hypernyms);
					for(String string : hypernymsStrings)
						if(dict.phraseEntryList(string)==null || dict.phraseEntryList(string).isEmpty())
							dict.addEntry(new DictionaryEntry<String>(string,newCategory));
				}
			}
		}
		this.dictionary = dict;
	}

	public MapDictionary<String> getDictionary() {
		return dictionary;
	}

	public String toString() {
		return dictionary.toString();
	}
}
